<html>
 <head>
  <meta charset="utf-8"/>
  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"/>
  <title>
   CNN卷积神经网络应用于人脸识别（详细流程+代码实现）  | 数螺 | NAUT IDEA
  </title>
  <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet"/>
  <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
  <style type="text/css">
   #xmain img {
                  max-width: 100%;
                  display: block;
                  margin-top: 10px;
                  margin-bottom: 10px;
                }

                #xmain p {
                    line-height:150%;
                    font-size: 16px;
                    margin-top: 20px;
                }

                #xmain h2 {
                    font-size: 24px;
                }

                #xmain h3 {
                    font-size: 20px;
                }

                #xmain h4 {
                    font-size: 18px;
                }


                .header {
	           background-color: #0099ff;
	           color: #ffffff;
	           margin-bottom: 20px;
	        }

	        .header p {
                  margin: 0px;
                  padding: 10px 0;
                  display: inline-block;  
                  vertical-align: middle;
                  font-size: 16px;
               }

               .header a {
                 color: white;
               }

              .header img {
                 height: 25px;
              }
  </style>
  <script src="http://cdn.bootcss.com/jquery/3.0.0/jquery.min.js">
  </script>
  <script src="http://nautstatic-10007657.file.myqcloud.com/static/css/readability.min.js" type="text/javascript">
  </script>
  <script type="text/javascript">
   $(document).ready(function() {
                 var loc = document.location;
                 var uri = {
                  spec: "http://dataunion.org/17618.html",
                  host: "http://dataunion.org",
                  prePath: "http://dataunion.org",
                  scheme: "http",
                  pathBase: "http://dataunion.org/"
                 };
    
                 var documentClone = document.cloneNode(true);
                 var article = new Readability(uri, documentClone).parse();
     
                 document.getElementById("xmain").innerHTML = article.content;
                });
  </script>
  <!-- 1466459662: Accept with keywords: (title(0.428571428571):社区,人脸识别,卷积,代码,数盟,神经网络,流程, topn(0.566666666667):初始化,定义,流程,个数,数盟,像素,分类器,神经网络,人脸,类别,文件,人脸识别,模型,python,参数,文章,数据,图片,函数,卷积,样本,算法,遍历,梯度下降,优化,代码,程序,图像,图片大小,数据库).-->
 </head>
 <body onload="">
  <div class="header">
   <div class="container">
    <div class="row">
     <div class="col-xs-6 col-sm-6 text-left">
      <a href="/databee">
       <img src="http://nautidea-10007657.cos.myqcloud.com/logo_white.png"/>
      </a>
      <a href="/databee">
       <p>
        数螺
       </p>
      </a>
     </div>
     <div class="hidden-xs col-sm-6 text-right">
      <p>
       致力于数据科学的推广和知识传播
      </p>
     </div>
    </div>
   </div>
  </div>
  <div class="container text-center">
   <h1>
    CNN卷积神经网络应用于人脸识别（详细流程+代码实现）
   </h1>
  </div>
  <div class="container" id="xmain">
   ﻿﻿
   <title>
    CNN卷积神经网络应用于人脸识别（详细流程+代码实现） | 数盟社区
   </title>
   <!-- All in One SEO Pack 2.2.7.6.2 by Michael Torbert of Semper Fi Web Design[32,74] -->
   <!-- /all in one seo pack -->
   <!--
<div align="center">
<a href="http://strata.oreilly.com.cn/hadoop-big-data-cn?cmp=mp-data-confreg-home-stcn16_dataunion_pc" target="_blank"><img src="http://dataunion.org/wp-content/uploads/2016/05/stratabj.jpg"/ ></a>
</div>
-->
   <header id="header-web">
    <div class="header-main">
     <hgroup class="logo">
      <h1>
       <a href="http://dataunion.org/" rel="home" title="数盟社区">
        <img src="http://dataunion.org/wp-content/themes/yzipi/images/logo.png"/>
       </a>
      </h1>
     </hgroup>
     <!--logo-->
     <nav class="header-nav">
      <ul class="menu" id="menu-%e4%b8%bb%e8%8f%9c%e5%8d%95">
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-71" id="menu-item-71">
        <a href="http://dataunion.org/category/events" title="events">
         活动
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-22457" id="menu-item-22457">
          <a href="http://dataunion.org/2016timeline">
           2016档期
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-22459" id="menu-item-22459">
          <a href="http://dataunion.org/category/parterc">
           合作会议
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor current-menu-parent current-post-parent menu-item-has-children menu-item-20869" id="menu-item-20869">
        <a href="http://dataunion.org/category/tech" title="articles">
         文章
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20867" id="menu-item-20867">
          <a href="http://dataunion.org/category/tech/base" title="base">
           基础架构
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3302" id="menu-item-3302">
          <a href="http://dataunion.org/category/tech/ai" title="ai">
           人工智能
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3303" id="menu-item-3303">
          <a href="http://dataunion.org/category/tech/analysis" title="analysis">
           数据分析
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21920" id="menu-item-21920">
          <a href="http://dataunion.org/category/tech/dm">
           数据挖掘
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3314" id="menu-item-3314">
          <a href="http://dataunion.org/category/tech/viz" title="viz">
           可视化
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3305" id="menu-item-3305">
          <a href="http://dataunion.org/category/tech/devl" title="devl">
           编程语言
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-20876" id="menu-item-20876">
        <a href="http://dataunion.org/category/industry">
         行业
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-16328" id="menu-item-16328">
          <a href="http://dataunion.org/category/industry/case" title="case">
           行业应用
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2112" id="menu-item-2112">
          <a href="http://dataunion.org/category/industry/demo" title="demo">
           Demo展示
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21562" id="menu-item-21562">
          <a href="http://dataunion.org/category/industry/news">
           行业资讯
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-311" id="menu-item-311">
        <a href="http://dataunion.org/category/sources" title="sources">
         资源
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20870" id="menu-item-20870">
        <a href="http://dataunion.org/category/books" title="book">
         图书
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21363" id="menu-item-21363">
        <a href="http://dataunion.org/category/training">
         课程
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-21853" id="menu-item-21853">
        <a href="http://dataunion.org/category/jobs">
         职位
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-22050" id="menu-item-22050">
          <a href="http://dataunion.org/category/career">
           职业规划
          </a>
         </li>
        </ul>
       </li>
      </ul>
     </nav>
     <!--header-nav-->
    </div>
   </header>
   <!--header-web-->
   <div id="main">
    <div id="soutab">
     <form action="http://dataunion.org/" class="search" method="get">
     </form>
    </div>
    <div id="container">
     <nav id="mbx">
      当前位置：
      <a href="http://dataunion.org">
       首页
      </a>
      &gt;
      <a href="http://dataunion.org/category/tech">
       文章
      </a>
      &gt;  正文
     </nav>
     <!--mbx-->
     <article class="content">
      <header align="centre" class="contenttitle">
       <div class="mscc">
        <h1 class="mscctitle">
         <a href="http://dataunion.org/17618.html">
          CNN卷积神经网络应用于人脸识别（详细流程+代码实现）
         </a>
        </h1>
        <address class="msccaddress ">
         <em>
          18,419 次阅读 -
         </em>
         <a href="http://dataunion.org/category/tech" rel="category tag">
          文章
         </a>
        </address>
       </div>
      </header>
      <div class="content-text">
       <blockquote>
        <p>
         作者：wepon   出处：
         <a href="http://blog.csdn.net/u012162613/article/details/43277187">
          wepon的博客
         </a>
        </p>
       </blockquote>
       <p>
        本文主要讲解将CNN应用于人脸识别的流程，程序基于python+numpy+theano+PIL开发，采用类似LeNet5的CNN模型，应用于olivettifaces人脸数据库，实现人脸识别的功能，模型的误差降到了5%以下。本程序只是个人学习过程的一个toy implement，样本很小，模型随时都会过拟合。
       </p>
       <p>
        但是，本文意在理清程序开发CNN模型的具体步骤，特别是针对图像识别，从拿到图像数据库，到实现一个针对这个图像数据库的CNN模型，我觉得本文对这些流程的实现具有参考意义。
       </p>
       <p>
        《本文目录》
       </p>
       <p>
        一、olivettifaces人脸数据库介绍
       </p>
       <p>
        二、CNN的基本“构件”（LogisticRegression、HiddenLayer、LeNetConvPoolLayer）
       </p>
       <p>
        三、组建CNN模型，设置优化算法，应用于Olivetti Faces进行人脸识别
       </p>
       <p>
        四、训练结果以及参数设置的讨论
       </p>
       <p>
        五、利用训练好的参数初始化模型
       </p>
       <p>
        六、一些需要说明的
       </p>
       <h2>
        <p name="t0">
        </p>
        一、olivettifaces人脸数据库介绍
       </h2>
       <p>
        <a href="http://dataunion.org/wp-content/uploads/2015/05/olivettifaces.gif" target="_blank">
         Olivetti Faces
        </a>
        是纽约大学的一个比较小的人脸库，由40个人的400张图片构成，即每个人的人脸图片为10张。每张图片的灰度级为8位，每个像素的灰度大小位于0-255之间，每张图片大小为64×64。如下图，这个图片大小是1190*942，一共有20*20张人脸，故每张人脸大小是（1190/20）*（942/20）即57*47=2679：
       </p>
       <p>
        <img src="http://dataunion.org/wp-content/uploads/2015/05/olivettifaces.gif"/>
       </p>
       <p>
        本文所用的训练数据就是这张图片，400个样本，40个类别，乍一看样本好像比较小，用CNN效果会好吗？先别下结论，请往下看。
       </p>
       <p>
        要运行CNN算法，这张图片必须先转化为数组（或者说矩阵），这个用到python的图像库PIL，几行代码就可以搞定，具体的方法我之前刚好写过一篇文章，也是用这张图，考虑到文章冗长，就不复制过来了，链接在此：
        <a href="http://blog.csdn.net/u012162613/article/details/43226127" target="_blank">
         《利用Python PIL、cPickle读取和保存图像数据库》
        </a>
        。
       </p>
       <p>
        训练机器学习算法，我们一般将原始数据分成训练数据（training_set）、验证数据(validation_set)、测试数据(testing_set)。本程序将training_set、validation_set、testing_set分别设置为320、40、40个样本。它们的label为0～39，对应40个不同的人。这部分的代码如下：
       </p>
       <div class="dp-highlighter bg_python">
        <div class="bar">
         <div class="tools">
          <b>
           [python]
          </b>
          <p>
          </p>
          <div>
          </div>
         </div>
        </div>
        <ol class="dp-py" start="1">
         <li class="alt">
          <span class="comment">
           “””
          </span>
         </li>
         <li class="">
          <span class="comment">
           加载图像数据的函数,dataset_path即图像olivettifaces的路径
          </span>
         </li>
         <li class="alt">
          <span class="comment">
           加载olivettifaces后，划分为train_data,valid_data,test_data三个数据集
          </span>
         </li>
         <li class="">
          <span class="comment">
           函数返回train_data,valid_data,test_data以及对应的label
          </span>
         </li>
         <li class="alt">
          <span class="comment">
           “””
          </span>
         </li>
         <li class="">
          <span class="keyword">
           def
          </span>
          load_data(dataset_path):
         </li>
         <li class="alt">
          img = Image.open(dataset_path)
         </li>
         <li class="">
          img_ndarray = numpy.asarray(img, dtype=
          <span class="string">
           ‘float64’
          </span>
          )/
          <span class="number">
           256
          </span>
         </li>
         <li class="alt">
          faces=numpy.empty((
          <span class="number">
           400
          </span>
          ,
          <span class="number">
           2679
          </span>
          ))
         </li>
         <li class="">
          <span class="keyword">
           for
          </span>
          row
          <span class="keyword">
           in
          </span>
          range(
          <span class="number">
           20
          </span>
          ):
         </li>
         <li class="alt">
          <span class="keyword">
           for
          </span>
          column
          <span class="keyword">
           in
          </span>
          range(
          <span class="number">
           20
          </span>
          ):
         </li>
         <li class="">
          faces[row*
          <span class="number">
           20
          </span>
          +column]=numpy.ndarray.flatten(img_ndarray [row*
          <span class="number">
           57
          </span>
          :(row+
          <span class="number">
           1
          </span>
          )*
          <span class="number">
           57
          </span>
          ,column*
          <span class="number">
           47
          </span>
          :(column+
          <span class="number">
           1
          </span>
          )*
          <span class="number">
           47
          </span>
          ])
         </li>
         <li class="alt">
         </li>
         <li class="">
          label=numpy.empty(
          <span class="number">
           400
          </span>
          )
         </li>
         <li class="alt">
          <span class="keyword">
           for
          </span>
          i
          <span class="keyword">
           in
          </span>
          range(
          <span class="number">
           40
          </span>
          ):
         </li>
         <li class="">
          label[i*
          <span class="number">
           10
          </span>
          :i*
          <span class="number">
           10
          </span>
          +
          <span class="number">
           10
          </span>
          ]=i
         </li>
         <li class="alt">
          label=label.astype(numpy.int)
         </li>
         <li class="">
         </li>
         <li class="alt">
          <span class="comment">
           #分成训练集、验证集、测试集，大小如下
          </span>
         </li>
         <li class="">
          train_data=numpy.empty((
          <span class="number">
           320
          </span>
          ,
          <span class="number">
           2679
          </span>
          ))
         </li>
         <li class="alt">
          train_label=numpy.empty(
          <span class="number">
           320
          </span>
          )
         </li>
         <li class="">
          valid_data=numpy.empty((
          <span class="number">
           40
          </span>
          ,
          <span class="number">
           2679
          </span>
          ))
         </li>
         <li class="alt">
          valid_label=numpy.empty(
          <span class="number">
           40
          </span>
          )
         </li>
         <li class="">
          test_data=numpy.empty((
          <span class="number">
           40
          </span>
          ,
          <span class="number">
           2679
          </span>
          ))
         </li>
         <li class="alt">
          test_label=numpy.empty(
          <span class="number">
           40
          </span>
          )
         </li>
         <li class="">
         </li>
         <li class="alt">
          <span class="keyword">
           for
          </span>
          i
          <span class="keyword">
           in
          </span>
          range(
          <span class="number">
           40
          </span>
          ):
         </li>
         <li class="">
          train_data[i*
          <span class="number">
           8
          </span>
          :i*
          <span class="number">
           8
          </span>
          +
          <span class="number">
           8
          </span>
          ]=faces[i*
          <span class="number">
           10
          </span>
          :i*
          <span class="number">
           10
          </span>
          +
          <span class="number">
           8
          </span>
          ]
         </li>
         <li class="alt">
          train_label[i*
          <span class="number">
           8
          </span>
          :i*
          <span class="number">
           8
          </span>
          +
          <span class="number">
           8
          </span>
          ]=label[i*
          <span class="number">
           10
          </span>
          :i*
          <span class="number">
           10
          </span>
          +
          <span class="number">
           8
          </span>
          ]
         </li>
         <li class="">
          valid_data[i]=faces[i*
          <span class="number">
           10
          </span>
          +
          <span class="number">
           8
          </span>
          ]
         </li>
         <li class="alt">
          valid_label[i]=label[i*
          <span class="number">
           10
          </span>
          +
          <span class="number">
           8
          </span>
          ]
         </li>
         <li class="">
          test_data[i]=faces[i*
          <span class="number">
           10
          </span>
          +
          <span class="number">
           9
          </span>
          ]
         </li>
         <li class="alt">
          test_label[i]=label[i*
          <span class="number">
           10
          </span>
          +
          <span class="number">
           9
          </span>
          ]
         </li>
         <li class="">
         </li>
         <li class="alt">
          <span class="comment">
           #将数据集定义成shared类型，才能将数据复制进GPU，利用GPU加速程序。
          </span>
         </li>
         <li class="">
          <span class="keyword">
           def
          </span>
          shared_dataset(data_x, data_y, borrow=
          <span class="special">
           True
          </span>
          ):
         </li>
         <li class="alt">
          shared_x = theano.shared(numpy.asarray(data_x,
         </li>
         <li class="">
          dtype=theano.config.floatX),
         </li>
         <li class="alt">
          borrow=borrow)
         </li>
         <li class="">
          shared_y = theano.shared(numpy.asarray(data_y,
         </li>
         <li class="alt">
          dtype=theano.config.floatX),
         </li>
         <li class="">
          borrow=borrow)
         </li>
         <li class="alt">
          <span class="keyword">
           return
          </span>
          shared_x, T.cast(shared_y,
          <span class="string">
           ‘int32’
          </span>
          )
         </li>
         <li class="">
         </li>
         <li class="alt">
         </li>
         <li class="">
         </li>
         <li class="alt">
          train_set_x, train_set_y = shared_dataset(train_data,train_label)
         </li>
         <li class="">
          valid_set_x, valid_set_y = shared_dataset(valid_data,valid_label)
         </li>
         <li class="alt">
          test_set_x, test_set_y = shared_dataset(test_data,test_label)
         </li>
         <li class="">
          rval = [(train_set_x, train_set_y), (valid_set_x, valid_set_y),
         </li>
         <li class="alt">
          (test_set_x, test_set_y)]
         </li>
         <li class="">
          <span class="keyword">
           return
          </span>
          rval
         </li>
        </ol>
       </div>
       <p>
       </p>
       <h2>
        <p name="t1">
        </p>
        二、CNN的基本“构件”（LogisticRegression、HiddenLayer、LeNetConvPoolLayer）
       </h2>
       <div>
       </div>
       <div>
        卷积神经网络（CNN）的基本结构就是输入层、卷积层（conv）、子采样层（pooling）、全连接层、输出层（分类器）。  卷积层+子采样层一般都会有若干个，本程序实现的CNN模型参考LeNet5，有两个“卷积+子采样层”LeNetConvPoolLayer。全连接层相当于MLP（多层感知机）中的隐含层HiddenLayer。输出层即分类器，一般采用softmax回归（也有人直接叫逻辑回归，其实就是多类别的logistics regression），本程序也直接用LogisticRegression表示。
       </div>
       <div>
       </div>
       <div>
        总结起来，要组建CNN模型，必须先定义LeNetConvPoolLayer、HiddenLayer、LogisticRegression这三种layer，这一点在我上一篇文章介绍CNN算法时讲得很详细，包括代码注解，因为太冗长，这里给出链接：
        <a href="http://blog.csdn.net/u012162613/article/details/43225445" target="_blank">
         《DeepLearning tutorial（4）CNN卷积神经网络原理简介+代码详解》
        </a>
        。
       </div>
       <div>
       </div>
       <p>
        代码太长，就不贴具体的了，只给出框架，具体可以下载我的代码看看：
       </p>
       <div class="dp-highlighter bg_python">
        <div class="bar">
         <div class="tools">
          <b>
           [python]
          </b>
         </div>
        </div>
        <ol class="dp-py" start="1">
         <li class="alt">
          <span class="comment">
           #分类器，即CNN最后一层，采用逻辑回归（softmax）
          </span>
         </li>
         <li class="">
          <span class="keyword">
           class
          </span>
          LogisticRegression(object):
         </li>
         <li class="alt">
          <span class="keyword">
           def
          </span>
          __init__(
          <span class="special">
           self
          </span>
          , input, n_in, n_out):
         </li>
         <li class="">
          <span class="special">
           self
          </span>
          .W = ….
         </li>
         <li class="alt">
          <span class="special">
           self
          </span>
          .b = ….
         </li>
         <li class="">
          <span class="special">
           self
          </span>
          .p_y_given_x = …
         </li>
         <li class="alt">
          <span class="special">
           self
          </span>
          .y_pred = …
         </li>
         <li class="">
          <span class="special">
           self
          </span>
          .params = …
         </li>
         <li class="alt">
          <span class="keyword">
           def
          </span>
          negative_log_likelihood(
          <span class="special">
           self
          </span>
          , y):
         </li>
         <li class="">
          <span class="keyword">
           def
          </span>
          errors(
          <span class="special">
           self
          </span>
          , y):
         </li>
         <li class="alt">
         </li>
         <li class="">
          <span class="comment">
           #全连接层，分类器前一层
          </span>
         </li>
         <li class="alt">
          <span class="keyword">
           class
          </span>
          HiddenLayer(object):
         </li>
         <li class="">
          <span class="keyword">
           def
          </span>
          __init__(
          <span class="special">
           self
          </span>
          , rng, input, n_in, n_out, W=
          <span class="special">
           None
          </span>
          , b=
          <span class="special">
           None
          </span>
          ,activation=T.tanh):
         </li>
         <li class="alt">
          <span class="special">
           self
          </span>
          .input = input
         </li>
         <li class="">
          <span class="special">
           self
          </span>
          .W = …
         </li>
         <li class="alt">
          <span class="special">
           self
          </span>
          .b = …
         </li>
         <li class="">
          lin_output = …
         </li>
         <li class="alt">
          <span class="special">
           self
          </span>
          .params = [
          <span class="special">
           self
          </span>
          .W,
          <span class="special">
           self
          </span>
          .b]
         </li>
         <li class="">
         </li>
         <li class="alt">
          <span class="comment">
           #卷积+采样层（conv+maxpooling）
          </span>
         </li>
         <li class="">
          <span class="keyword">
           class
          </span>
          LeNetConvPoolLayer(object):
         </li>
         <li class="alt">
          <span class="keyword">
           def
          </span>
          __init__(
          <span class="special">
           self
          </span>
          , rng, input, filter_shape, image_shape, poolsize=(
          <span class="number">
           2
          </span>
          ,
          <span class="number">
           2
          </span>
          )):
         </li>
         <li class="">
          <span class="special">
           self
          </span>
          .input = input
         </li>
         <li class="alt">
          <span class="special">
           self
          </span>
          .W = …
         </li>
         <li class="">
          <span class="special">
           self
          </span>
          .b = …
         </li>
         <li class="alt">
          <span class="comment">
           # 卷积
          </span>
         </li>
         <li class="">
          conv_out = …
         </li>
         <li class="alt">
          <span class="comment">
           # 子采样
          </span>
         </li>
         <li class="">
          pooled_out =…
         </li>
         <li class="alt">
          <span class="special">
           self
          </span>
          .output = …
         </li>
         <li class="">
          <span class="special">
           self
          </span>
          .params = [
          <span class="special">
           self
          </span>
          .W,
          <span class="special">
           self
          </span>
          .b]
         </li>
        </ol>
       </div>
       <h2>
        <p name="t2">
        </p>
        三、组建CNN模型，设置优化算法，应用于Olivetti Faces进行人脸识别
       </h2>
       <p>
        上面定义好了CNN的几个基本“构件”，现在我们使用这些构件来组建CNN模型，本程序的CNN模型参考LeNet5，具体为：input+layer0(LeNetConvPoolLayer)+layer1(LeNetConvPoolLayer)+layer2(HiddenLayer)+layer3(LogisticRegression)
       </p>
       <p>
        这是一个串联结构，代码也很好写，直接用第二部分定义好的各种layer去组建就行了，上一layer的输出接下一layer的输入，具体可以看看代码evaluate_olivettifaces函数中的“建立CNN模型”部分。
       </p>
       <p>
        CNN模型组建好了，就剩下用优化算法求解了，优化算法采用批量随机梯度下降算法（MSGD），所以要先定义MSGD的一些要素，主要包括：代价函数，训练、验证、测试model、参数更新规则（即梯度下降）。这部分的代码在evaluate_olivettifaces函数中的“定义优化算法的一些基本要素”部分。
       </p>
       <p>
        优化算法的基本要素也定义好了，接下来就要运用人脸图像数据集来训练这个模型了，训练过程有训练步数（n_epoch）的设置，每个epoch会遍历所有的训练数据（training_set），本程序中也就是320个人脸图。还有迭代次数iter，一次迭代遍历一个batch里的所有样本，具体为多少要看所设置的batch_size。关于参数的设定我在下面会讨论。这一部分的代码在evaluate_olivettifaces函数中的“训练CNN阶段”部分。
       </p>
       <p>
        代码很长，只贴框架，具体可以下载我的代码看看：
       </p>
       <div class="dp-highlighter bg_python">
        <div class="bar">
         <div class="tools">
          <b>
           [python]
          </b>
          <p>
          </p>
          <div>
          </div>
         </div>
        </div>
        <ol class="dp-py" start="1">
         <li class="alt">
          <span class="keyword">
           def
          </span>
          evaluate_olivettifaces(learning_rate=
          <span class="number">
           0.05
          </span>
          , n_epochs=
          <span class="number">
           200
          </span>
          ,
         </li>
         <li class="">
          dataset=
          <span class="string">
           ‘olivettifaces.gif’
          </span>
          ,
         </li>
         <li class="alt">
          nkerns=[
          <span class="number">
           5
          </span>
          ,
          <span class="number">
           10
          </span>
          ], batch_size=
          <span class="number">
           40
          </span>
          ):
         </li>
         <li class="">
         </li>
         <li class="alt">
          <span class="comment">
           #随机数生成器，用于初始化参数….
          </span>
         </li>
         <li class="">
          <span class="comment">
           #加载数据…..
          </span>
         </li>
         <li class="alt">
          <span class="comment">
           #计算各数据集的batch个数….
          </span>
         </li>
         <li class="">
          <span class="comment">
           #定义几个变量，x代表人脸数据，作为layer0的输入……
          </span>
         </li>
         <li class="alt">
         </li>
         <li class="">
          <span class="comment">
           ######################
          </span>
         </li>
         <li class="alt">
          <span class="comment">
           #建立CNN模型:
          </span>
         </li>
         <li class="">
          <span class="comment">
           #input+layer0(LeNetConvPoolLayer)+layer1(LeNetConvPoolLayer)+layer2(HiddenLayer)+layer3(LogisticRegression)
          </span>
         </li>
         <li class="alt">
          <span class="comment">
           ######################
          </span>
         </li>
         <li class="">
          …
         </li>
         <li class="alt">
          ….
         </li>
         <li class="">
          ……
         </li>
         <li class="alt">
         </li>
         <li class="">
          <span class="comment">
           #########################
          </span>
         </li>
         <li class="alt">
          <span class="comment">
           # 定义优化算法的一些基本要素：代价函数，训练、验证、测试model、参数更新规则（即梯度下降）
          </span>
         </li>
         <li class="">
          <span class="comment">
           #########################
          </span>
         </li>
         <li class="alt">
          …
         </li>
         <li class="">
          ….
         </li>
         <li class="alt">
          ……
         </li>
         <li class="">
         </li>
         <li class="alt">
          <span class="comment">
           #########################
          </span>
         </li>
         <li class="">
          <span class="comment">
           # 训练CNN阶段，寻找最优的参数。
          </span>
         </li>
         <li class="alt">
          <span class="comment">
           ########################
          </span>
         </li>
         <li class="">
          …
         </li>
         <li class="alt">
          …..
         </li>
         <li class="">
          …….
         </li>
        </ol>
       </div>
       <p>
       </p>
       <p>
        另外，值得一提的是，在训练CNN阶段，我们必须定时地保存模型的参数，这是在训练机器学习算法时一个经常会做的事情，这一部分的详细介绍我之前写过一篇文章
        <a href="http://blog.csdn.net/u012162613/article/details/43169019" target="_blank">
         《DeepLearning tutorial（2）机器学习算法在训练过程中保存参数》
        </a>
        。简单来说，我们要保存CNN模型中layer0、layer1、layer2、layer3的参数，所以在“训练CNN阶段”这部分下面，有一句代码：
       </p>
       <div class="dp-highlighter bg_python">
        <div class="bar">
         <div class="tools">
          <b>
           [python]
          </b>
          <p>
          </p>
          <div>
          </div>
         </div>
        </div>
        <ol class="dp-py" start="1">
         <li class="alt">
          save_params(layer0.params,layer1.params,layer2.params,layer3.params)
         </li>
        </ol>
       </div>
       <p>
        这个函数具体定义为：
       </p>
       <div class="dp-highlighter bg_python">
        <div class="bar">
         <div class="tools">
          <b>
           [python]
          </b>
          <p>
          </p>
          <div>
          </div>
         </div>
        </div>
        <ol class="dp-py" start="1">
         <li class="alt">
          <span class="comment">
           #保存训练参数的函数
          </span>
         </li>
         <li class="">
          <span class="keyword">
           def
          </span>
          save_params(param1,param2,param3,param4):
         </li>
         <li class="alt">
          <span class="keyword">
           import
          </span>
          cPickle
         </li>
         <li class="">
          write_file = open(
          <span class="string">
           ‘params.pkl’
          </span>
          ,
          <span class="string">
           ‘wb’
          </span>
          )
         </li>
         <li class="alt">
          cPickle.dump(param1, write_file, –
          <span class="number">
           1
          </span>
          )
         </li>
         <li class="">
          cPickle.dump(param2, write_file, –
          <span class="number">
           1
          </span>
          )
         </li>
         <li class="alt">
          cPickle.dump(param3, write_file, –
          <span class="number">
           1
          </span>
          )
         </li>
         <li class="">
          cPickle.dump(param4, write_file, –
          <span class="number">
           1
          </span>
          )
         </li>
         <li class="alt">
          write_file.close()
         </li>
        </ol>
       </div>
       <p>
       </p>
       <p>
        如果在其他算法中，你要保存的参数有五个六个甚至更多，那么改一下这个函数的参数就行啦。
       </p>
       <h2>
        <p name="t3">
        </p>
        四、训练结果以及参数设置的讨论
       </h2>
       <div>
       </div>
       <div>
        ok，上面基本介绍完了CNN模型的构建，以及模型的训练，我将它们的代码都放在train_CNN_olivettifaces.py这个源文件中，将
        <a href="http://dataunion.org/wp-content/uploads/2015/05/olivettifaces.gif" target="_blank">
         Olivetti Faces
        </a>
        这张图片跟这个代码文件放在同个目录下，运行这个文件，几分钟就可以训练完模型，并且在同个目录下得到一个params.pkl文件，这个文件保存的就是最后的模型的参数，方便你以后直接使用这个模型。
       </div>
       <div>
       </div>
       <div>
        好了，现在讨论一下怎么设置参数，具体来说，程序中可以设置的参数包括：学习速率learning_rate、batch_size、n_epochs、nkerns、poolsize。下面逐一讨论调节它们时对模型的影响。
       </div>
       <div>
       </div>
       <div>
        <ul>
         <li>
          调节learning_rate
         </li>
        </ul>
        <p>
         学习速率learning_rate就是运用SGD算法时梯度前面的系数，非常重要，设得太大的话算法可能永远都优化不了，设得太小会使算法优化得太慢，而且可能还会掉入局部最优。可以形象地将learning_rate比喻成走路时步子的大小，想象一下要从一个U形的山谷的一边走到山谷最低点，如果步子特别大，像巨人那么大，那会直接从一边跨到另一边，然后又跨回这边，如此往复。如果太小了，可能你走着走着就掉入了某些小坑，因为山路总是凹凸不平的（局部最优），掉入这些小坑后，如果步子还是不变，就永远走不出那个坑。
        </p>
       </div>
       <div>
       </div>
       <div>
        好，回到本文的模型，下面是我使用时的记录，固定其他参数，调节learning_rate：
       </div>
       <div>
        （1）kerns=[20, 50], batch_size=40，poolsize=（2，2），learning_rate=0.1时，validation-error一直是97.5%，没降下来，分析了一下，觉得应该是学习速率太大，跳过了最优。
        <p>
        </p>
        <p>
         （2）nkerns=[20, 50], batch_size=40，poolsize=（2，2），learning_rate=0.01时，训练到epoch 60多时，validation-error降到5%，test-error降到15%
        </p>
        <p>
         （3）nkerns=[20, 50], batch_size=40，poolsize=（2，2），learning_rate=0.05时，训练到epoch 36时，validation-error降到2.5%，test-error降到5%
        </p>
       </div>
       <div>
        注意，验证集和测试集都只有40张图片，也就是说只有一两张识别错了，还是不错的，数据集再大点，误差率可以降到更小。最后我将learning_rate设置为0.05。
        <p>
        </p>
        <p>
         PS：学习速率应该自适应地减小，是有专门的一些算法的，本程序没有实现这个功能，有时间再研究一下。
        </p>
       </div>
       <div>
       </div>
       <p>
       </p>
       <ul>
        <li>
         调节batch_size
        </li>
       </ul>
       <p>
        因为我们采用minibatch SGD算法来优化，所以是一个batch一个batch地将数据输入CNN模型中，然后计算这个batch的所有样本的平均损失，即代价函数是所有样本的平均。而batch_size就是一个batch的所包含的样本数，显然batch_size将影响到模型的优化程度和速度。
       </p>
       <p>
        回到本文的模型，首先因为我们train_dataset是320，valid_dataset和test_dataset都是40，所以batch_size最好都是40的因子，也就是能让40整除，比如40、20、10、5、2、1，否则会浪费一些样本，比如设置为30，则320/30=10，余数时20，这20个样本是没被利用的。并且，如果batch_size设置为30，则得出的validation-error和test-error只是30个样本的错误率，并不是全部40个样本的错误率。这是设置batch_size要注意的。特别是样本比较少的时候。
        <br/>
        下面是我实验时的记录，固定其他参数，改变batch_size:
        <br/>
        batch_size=1、2、5、10、20时，validation-error一直是97.5%，没降下来。我觉得可能是样本类别覆盖率过小，因为我们的数据是按类别排的，每个类别10个样本是连续排在一起的，batch_size等于20时其实只包含了两个类别，这样优化会很慢。
       </p>
       <p>
        因此最后我将batch_size设为40，也就是valid_dataset和test_dataset的大小了，没办法，原始数据集样本太少了。一般我们都不会让batch_size达到valid_dataset和test_dataset的大小的。
       </p>
       <ul>
        <li>
         关于n_epochs
        </li>
       </ul>
       <p>
        n_epochs也就是最大的训练步数，比如设为200，那训练过程最多遍历你的数据集200遍，当遍历了200遍你的dataset时，程序会停止。n_epochs就相当于一个停止程序的控制参数，并不会影响CNN模型的优化程度和速度，只是一个控制程序结束的参数。
       </p>
       <ul>
        <li>
         nkerns=[20, 50]
        </li>
       </ul>
       <p>
        20表示第一个卷积层的卷积核的个数，50表示第二个卷积层的卷积核的个数。这个我也是瞎调的，暂时没什么经验可以总结。
        <br/>
        不过从理论上来说，卷积核的个数其实就代表了特征的个数，你提取的特征越多，可能最后分类就越准。但是，特征太多（卷积核太多），会增加参数的规模，加大了计算复杂度，而且有时候卷积核也不是越多越好，应根据具体的应用对象来确定。所以我觉得，CNN虽号称自动提取特征，免去复杂的特征工程，但是很多参数比如这里的nkerns还是需要去调节的，还是需要一些“人工”的。
        <br/>
        下面是我的实验记录，固定batch_size=40，learning_rate=0.05，poolsize=（2，2）：
       </p>
       <p>
        （1）nkerns=[20, 50]时，训练到epoch 36时，validation-error降到2.5%，test-error降到5%
       </p>
       <p>
        （2）nkerns=[10, 30]时，训练到epoch 46时，validation-error降到5%，test-error降到5%
       </p>
       <p>
        （3）nkerns=[5, 10]时，训练到epoch 38时，validation-error降到5%，test-error降到7.5%
       </p>
       <ul>
        <li>
         poolsize=(2, 2)
        </li>
       </ul>
       <p>
        poolzize在本程序中是设置为(2,2)，即从一个2*2的区域里maxpooling出1个像素，说白了就算4和像素保留成1个像素。本例程中人脸图像大小是57*47，对这种小图像来说，(2,2)时比较合理的。如果你用的图像比较大，可以把poolsize设的大一点。
       </p>
       <p>
        +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++分割线+++++++++++++++++++++++++++++++++++++++++++
       </p>
       <p>
        上面部分介绍完了CNN模型构建以及模型训练的过程，代码都在train_CNN_olivettifaces.py里面，训练完可以得到一个params.pkl文件，这个文件保存的就是最后的模型的参数，方便你以后直接使用这个模型。以后只需利用这些保存下来的参数来初始化CNN模型，就得到一个可以使用的CNN系统，将人脸图输入这个CNN系统，预测人脸图的类别。
       </p>
       <p>
        接下来就介绍怎么使用训练好的参数的方法，这部分的代码放在use_CNN_olivettifaces.py文件中。
       </p>
       <h2>
        <p name="t4">
        </p>
        五、利用训练好的参数初始化模型
       </h2>
       <div>
       </div>
       <div>
        在train_CNN_olivettifaces.py中的LeNetConvPoolLayer、HiddenLayer、LogisticRegression是用随机数生成器去随机初始化的，我们将它们定义为可以用参数来初始化的版本，其实很简单，代码只需要做稍微的改动，只需要在LogisticRegression、HiddenLayer、LeNetConvPoolLayer这三个class的__init__()函数中加两个参数params_W,params_b，然后将params_W,params_b赋值给这三个class里的W和b：
       </div>
       <div>
       </div>
       <div>
        <div class="dp-highlighter bg_python">
         <div class="bar">
          <div class="tools">
           <b>
            [python]
           </b>
          </div>
         </div>
         <ol class="dp-py" start="1">
          <li class="alt">
           <span class="special">
            self
           </span>
           .W = params_W
          </li>
          <li class="">
           <span class="special">
            self
           </span>
           .b = params_b
          </li>
         </ol>
        </div>
        <p>
         params_W,params_b就是从params.pkl文件中读取来的，读取的函数：
        </p>
       </div>
       <div>
        <div class="dp-highlighter bg_python">
         <div class="bar">
          <div class="tools">
           <b>
            [python]
           </b>
           <p>
           </p>
           <div>
           </div>
          </div>
         </div>
         <ol class="dp-py" start="1">
          <li class="alt">
           <span class="comment">
            #读取之前保存的训练参数
           </span>
          </li>
          <li class="">
           <span class="comment">
            #layer0_params~layer3_params都是包含W和b的,layer*_params[0]是W，layer*_params[1]是b
           </span>
          </li>
          <li class="alt">
           <span class="keyword">
            def
           </span>
           load_params(params_file):
          </li>
          <li class="">
           f=open(params_file,
           <span class="string">
            ‘rb’
           </span>
           )
          </li>
          <li class="alt">
           layer0_params=cPickle.load(f)
          </li>
          <li class="">
           layer1_params=cPickle.load(f)
          </li>
          <li class="alt">
           layer2_params=cPickle.load(f)
          </li>
          <li class="">
           layer3_params=cPickle.load(f)
          </li>
          <li class="alt">
           f.close()
          </li>
          <li class="">
           <span class="keyword">
            return
           </span>
           layer0_params,layer1_params,layer2_params,layer3_params
          </li>
         </ol>
        </div>
       </div>
       <div>
        ok，可以用参数初始化的CNN定义好了，那现在就将需要测试的人脸图输入该CNN，测试其类别。同样的，需要写一个读图像的函数load_data()，代码就不贴了。将图像数据输入，CNN的输出便是该图像的类别，这一部分的代码在use_CNN()函数中，代码很容易看懂。
       </div>
       <div>
       </div>
       <div>
        这一部分还涉及到theano.function的使用，我把一些笔记记在了use_CNN_olivettifaces.py代码的最后，因为跟代码相关，结合代码来看会比较好，所以下面就不讲这部分，有兴趣的看看代码。
       </div>
       <div>
       </div>
       <div>
        最后说说测试的结果，我仍然以整副olivettifaces.gif作为输入，得出其类别后，跟真正的label对比，程序输出被错分的那些图像，运行结果如下：
       </div>
       <div>
       </div>
       <div>
       </div>
       <div>
       </div>
       <div>
        错了五张，我标了三张：
       </div>
       <div>
       </div>
       <div>
       </div>
       <h2>
        <p name="t5">
        </p>
        六、一些需要说明的
       </h2>
       <div>
       </div>
       <div>
        首先是本文的严谨性：在文章开头我就说这只是一个toy implement，400张图片根本不适合用DL来做。
       </div>
       <div>
        当然我写这篇文章，只是为了总结一下这个实现流程，这一点希望对读者也有参考意义。
       </div>
       <div>
       </div>
       <div>
        最后，我的代码都放在这里：
        <a href="https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/FaceRecognition_CNN(olivettifaces)" target="_blank">
         github地址，可以下载
        </a>
       </div>
      </div>
      <div>
       <strong>
        注：转载文章均来自于公开网络，仅供学习使用，不会用于任何商业用途，如果侵犯到原作者的权益，请您与我们联系删除或者授权事宜，联系邮箱：contact@dataunion.org。转载数盟网站文章请注明原文章作者，否则产生的任何版权纠纷与数盟无关。
       </strong>
      </div>
      <!--content_text-->
      <div class="fenxian">
       <!-- JiaThis Button BEGIN -->
       <div class="jiathis_style_32x32">
        <p class="jiathis_button_weixin">
        </p>
        <p class="jiathis_button_tsina">
        </p>
        <p class="jiathis_button_qzone">
        </p>
        <p class="jiathis_button_cqq">
        </p>
        <p class="jiathis_button_tumblr">
        </p>
        <a class="jiathis jiathis_txt jtico jtico_jiathis" href="http://www.jiathis.com/share" target="_blank">
        </a>
        <p class="jiathis_counter_style">
        </p>
       </div>
       <!-- JiaThis Button END -->
      </div>
     </article>
     <!--content-->
     <!--相关文章-->
     <div class="xianguan">
      <div class="xianguantitle">
       相关文章！
      </div>
      <ul class="pic">
       <li>
        <a href="http://dataunion.org/20231.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/08/QQ截图20150802215012_副本-300x283.png"/>
        </a>
        <a class="link" href="http://dataunion.org/20231.html" rel="bookmark" title="提高人脸检测性能新模型 HPM">
         提高人脸检测性能新模型 HPM
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/20119.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/07/face-detection-recognition-web-service-api-sdk_副本.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/20119.html" rel="bookmark" title="盘点：人脸检测和识别的Web服务API大全！">
         盘点：人脸检测和识别的Web服务API大全！
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/20010.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/07/t0189bad891542a6a7b_副本.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/20010.html" rel="bookmark" title="DeepFace——Facebook的人脸识别">
         DeepFace——Facebook的人脸识别
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/19866.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/06/QQ截图20150630213749_副本.png"/>
        </a>
        <a class="link" href="http://dataunion.org/19866.html" rel="bookmark" title="从How-Old.net到TwinsOrNot.net，看人脸识别技术是怎么 high 起来的">
         从How-Old.net到TwinsOrNot.net，看人脸识别技术是怎么 high 起来的
        </a>
       </li>
      </ul>
     </div>
     <!--相关文章-->
     <div class="comment" id="comments">
      <!-- You can start editing here. -->
      <ul id="comment">
       <li id="comment-12903">
        <span>
         <p class="avatar" href="" target="_blank">
          <img src="https://secure.gravatar.com/avatar/229587f8bb374bf5b997565cee958bde?s=86"/>
         </p>
        </span>
        <div class="mhcc">
         <address>
          lemon - 
						2015/12/14
         </address>
         <p>
          <img src="http://dataunion.org/wp-includes/images/smilies/mrgreen.png"/>
          大神
         </p>
        </div>
       </li>
       <!-- #comment-## -->
       <li id="comment-12945">
        <span>
         <p class="avatar" href="" target="_blank">
          <img src="https://secure.gravatar.com/avatar/7bf26ea78659a9aa7eb5cfb9e3618ef2?s=86"/>
         </p>
        </span>
        <div class="mhcc">
         <address>
          xyy_blcu - 
						2016/03/16
         </address>
         <p>
          第一段，开始说这个数据库的图片大小是64*64,然后仔细一说又是57*47，请问逻辑在哪里。。。。。。
         </p>
        </div>
       </li>
       <!-- #comment-## -->
      </ul>
      <div class="title">
       期待你一针见血的评论，Come on！
      </div>
      <div id="respond">
       <p>
        不用想啦，马上
        <a href="http://dataunion.org/wp-login.php?redirect_to=http%3A%2F%2Fdataunion.org%2F17618.html">
         "登录"
        </a>
        发表自已的想法.
       </p>
      </div>
     </div>
     <!-- .nav-single -->
    </div>
    <!--Container End-->
    <aside id="sitebar">
     <div class="sitebar_list2">
      <div class="wptag">
       <span class="tagtitle">
        热门标签+
       </span>
       <div class="tagg">
        <ul class="menu" id="menu-%e5%8f%8b%e6%83%85%e9%93%be%e6%8e%a5">
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1605" id="menu-item-1605">
          <a href="http://taidizh.com/">
           泰迪智慧
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-20884" id="menu-item-20884">
          <a href="http://www.transwarp.cn/">
           星环科技
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-3538" id="menu-item-3538">
          <a href="http://datall.org/">
           珈和遥感
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-20888" id="menu-item-20888">
          <a href="http://www.chinahadoop.cn/">
           小象学院
          </a>
         </li>
        </ul>
       </div>
      </div>
     </div>
     <div class="sitebar_list">
      <div class="textwidget">
       <div align="center">
        <a href="http://study.163.com/course/courseMain.htm?courseId=991022" target="_blank">
         <img src="http://dataunion.org/wp-content/uploads/2016/03/dv.jpg"/>
        </a>
       </div>
      </div>
     </div>
     <div class="sitebar_list">
      <h4 class="sitebar_title">
       文章分类
      </h4>
      <div class="tagcloud">
       <a class="tag-link-44" href="http://dataunion.org/category/industry/demo" style="font-size: 10.204724409449pt;" title="4个话题">
        Demo展示
       </a>
       <a class="tag-link-31" href="http://dataunion.org/category/experts" style="font-size: 15.826771653543pt;" title="52个话题">
        专家团队
       </a>
       <a class="tag-link-870" href="http://dataunion.org/category/tech/ai" style="font-size: 19.795275590551pt;" title="273个话题">
        人工智能
       </a>
       <a class="tag-link-488" href="http://dataunion.org/category/%e5%8a%a0%e5%85%a5%e6%95%b0%e7%9b%9f" style="font-size: 8pt;" title="1个话题">
        加入数盟
       </a>
       <a class="tag-link-869" href="http://dataunion.org/category/tech/viz" style="font-size: 17.204724409449pt;" title="93个话题">
        可视化
       </a>
       <a class="tag-link-30" href="http://dataunion.org/category/partners" style="font-size: 10.645669291339pt;" title="5个话题">
        合作伙伴
       </a>
       <a class="tag-link-889" href="http://dataunion.org/category/parterc" style="font-size: 11.582677165354pt;" title="8个话题">
        合作会议
       </a>
       <a class="tag-link-104" href="http://dataunion.org/category/books" style="font-size: 12.96062992126pt;" title="15个话题">
        图书
       </a>
       <a class="tag-link-220" href="http://dataunion.org/category/tech/base" style="font-size: 19.850393700787pt;" title="281个话题">
        基础架构
       </a>
       <a class="tag-link-219" href="http://dataunion.org/category/tech/analysis" style="font-size: 19.409448818898pt;" title="232个话题">
        数据分析
       </a>
       <a class="tag-link-887" href="http://dataunion.org/category/tech/dm" style="font-size: 13.291338582677pt;" title="17个话题">
        数据挖掘
       </a>
       <a class="tag-link-34" href="http://dataunion.org/category/tech" style="font-size: 20.732283464567pt;" title="404个话题">
        文章
       </a>
       <a class="tag-link-1" href="http://dataunion.org/category/uncategorized" style="font-size: 22pt;" title="693个话题">
        未分类
       </a>
       <a class="tag-link-4" href="http://dataunion.org/category/events" style="font-size: 14.503937007874pt;" title="29个话题">
        活动
       </a>
       <a class="tag-link-890" href="http://dataunion.org/category/tech/%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0" style="font-size: 10.204724409449pt;" title="4个话题">
        深度学习
       </a>
       <a class="tag-link-221" href="http://dataunion.org/category/tech/devl" style="font-size: 18.968503937008pt;" title="193个话题">
        编程语言
       </a>
       <a class="tag-link-888" href="http://dataunion.org/category/career" style="font-size: 15.661417322835pt;" title="48个话题">
        职业规划
       </a>
       <a class="tag-link-5" href="http://dataunion.org/category/jobs" style="font-size: 14.11811023622pt;" title="25个话题">
        职位
       </a>
       <a class="tag-link-871" href="http://dataunion.org/category/industry" style="font-size: 15.716535433071pt;" title="49个话题">
        行业
       </a>
       <a class="tag-link-613" href="http://dataunion.org/category/industry/case" style="font-size: 16.984251968504pt;" title="84个话题">
        行业应用
       </a>
       <a class="tag-link-885" href="http://dataunion.org/category/industry/news" style="font-size: 17.425196850394pt;" title="102个话题">
        行业资讯
       </a>
       <a class="tag-link-10" href="http://dataunion.org/category/training" style="font-size: 14.228346456693pt;" title="26个话题">
        课程
       </a>
       <a class="tag-link-16" href="http://dataunion.org/category/sources" style="font-size: 15.661417322835pt;" title="48个话题">
        资源
       </a>
      </div>
     </div>
     <div class="sitebar_list">
      <h4 class="sitebar_title">
       功能
      </h4>
      <ul>
       <li>
        <a href="http://dataunion.org/wp-login.php?action=register">
         注册
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/wp-login.php">
         登录
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/feed">
         文章
         <abbr title="Really Simple Syndication">
          RSS
         </abbr>
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/comments/feed">
         评论
         <abbr title="Really Simple Syndication">
          RSS
         </abbr>
        </a>
       </li>
       <li>
        <a href="https://cn.wordpress.org/" title="基于WordPress，一个优美、先进的个人信息发布平台。">
         WordPress.org
        </a>
       </li>
      </ul>
     </div>
    </aside>
    <div class="clear">
    </div>
   </div>
   <!--main-->
   ﻿
   <footer id="dibu">
    <div class="about">
     <div class="right">
      <ul class="menu" id="menu-%e5%ba%95%e9%83%a8%e8%8f%9c%e5%8d%95">
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-18024" id="menu-item-18024">
        <a href="http://dataunion.org/category/partners">
         合作伙伴
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-20881" id="menu-item-20881">
        <a href="http://dataunion.org/contribute">
         文章投稿
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20872" id="menu-item-20872">
        <a href="http://dataunion.org/category/%e5%8a%a0%e5%85%a5%e6%95%b0%e7%9b%9f">
         加入数盟
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-22441" id="menu-item-22441">
        <a href="http://dataunion.org/f-links">
         友情链接
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-20874" id="menu-item-20874">
        <a href="http://dataunion.org/aboutus">
         关于数盟
        </a>
       </li>
      </ul>
      <p class="banquan">
       数盟社区        ，
        做最棒的数据科学社区
      </p>
     </div>
     <div class="left">
      <ul class="bottomlist">
       <li>
        <a href="http://weibo.com/DataScientistUnion  " target="_blank" 　title="">
         <img src="http://dataunion.org/wp-content/themes/yzipi/images/weibo.png"/>
        </a>
       </li>
       <li>
        <a class="cd-popup-trigger" href="http://dataunion.org/17618.html#0">
         <img src="http://dataunion.org/wp-content/themes/yzipi/images/weixin.png"/>
        </a>
       </li>
      </ul>
      <div class="cd-popup">
       <div class="cd-popup-container">
        <h1>
         扫描二维码,加微信公众号
        </h1>
        <img src="http://dataunion.org/wp-content/themes/yzipi/images/2014-12-06-1515289049.png"/>
        <a class="cd-popup-close" href="http://dataunion.org/17618.html">
        </a>
       </div>
       <!-- cd-popup-container -->
      </div>
      <!-- cd-popup -->
     </div>
    </div>
    <!--about-->
    <div class="bottom">
     <a href="http://dataunion.org/">
      数盟社区
     </a>
     <a href="http://www.miitbeian.gov.cn/" rel="external nofollow" target="_blank">
      京ICP备14026740号
     </a>
     联系我们：
     <a href="mailto:contact@dataunion.org" target="_blank">
      contact@dataunion.org
     </a>
     <div class="tongji">
     </div>
     <!--bottom-->
     <div class="scroll" id="scroll" style="display:none;">
      ︿
     </div>
    </div>
   </footer>
   <!--dibu-->
  </div>
 </body>
</html>